// pages/statistics_report/statistics_report.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    tableName: '查询报表',

    quickFlag: false,
    searchList: [],
    searchWhere: [],
    searchVal: '',

    tableHtml: '',
  },

  toggleFlag(e) {
    this.setData({
      quickFlag: !this.data.quickFlag,
    })
  },
  searchQuick(e) {
    let searchObj = e.detail,
        searchWhere = []
    Object.entries(searchObj).forEach(([key, value]) => {
      let { type, val, } = value
      if(type === 'date') {
        let { startDate, endDate, } = val
        if(startDate) {
          let dfltLen = startDate.split('-').length
          if(dfltLen === 1) startDate += '-01-01'
          else if(dfltLen === 2) startDate += '-01'

          searchWhere.push({
            CompareValue: startDate + ' 00:00:00',
            CompareWith: key,
            Operator: '>=',
            or: 0,
          })
        }
        if(endDate) {
          let dfltLen = endDate.split('-').length
          if(dfltLen === 1) endDate += '-01-01'
          else if(dfltLen === 2) endDate += '-01'

          let endArr = endDate.split('-'),
              end = wx.$util.formatDate(new Date(endArr[0], Number(endArr[1]) - 1, Number(endArr[2]) + 1), 'yyyy-MM-dd')
          searchWhere.push({
            CompareValue: end + ' 00:00:00',
            CompareWith: key,
            Operator: '<',
            or: 0,
          })
        }
      } else {
        searchWhere.push({
          CompareValue: val,
          CompareWith: key,
          Operator: '=',
          or: 0,
        })
      }
    })
    this.setData({
      searchWhere,
    })
    this.getReportHtml()
  },
  setSearchVal() {
    let { searchList, searchWhere, } = this.data,
        arr = [],
        searchObj = {}
    searchWhere.forEach(item => {
      let fieldId = item.CompareWith,
          field = searchList.filter(field => field.field_id === fieldId)[0],
          name = field.field_name,
          type = field.type,
          val = item.CompareValue
      if(type === 'date') {
        if(!searchObj[name]) searchObj[name] = []
        searchObj[name].push(val.split(' ')[0])
      } else if(type === 'reference1') {
        let opt = field.optionList.filter(opt => val === opt[field.optionId])[0],
            optName = opt ? opt[field.optionName] : val
        searchObj[name] = optName
      } else {
        searchObj[name] = val
      }
    })
    Object.entries(searchObj).forEach(([key, val]) => {
      val = Array.isArray(val) ? val.join('-') : val
      arr.push(`${key}：${val}`)
    })
    this.setData({
      searchVal: arr.join('，'),
    })
  },

  // 接口
  // 获取定义模块
  getTable() {
    let post = {
      parent_row_id: this.reportid,
      row_id: 0,
    }
    return new Promise((resolve, reject) => {
      wx.$post(1, 'StatsReport/select_all_report_table', post).then(res => {
        if(res.errcode !== 0) return
        let rows = res.data.row,
            tableAlias = {}
        rows.forEach(row => {
          tableAlias[row.table_alias] = row.table_id
        })
        this.tableAlias = tableAlias
        resolve()
      })
    })
  },
  // 获取自定义搜索字段
  getReportField() {
    let post = {
      parent_row_id: this.reportid,
      row_id: 0,
    }
    wx.$post(1, 'StatsReport/select_all_report_field', post).then(res => {
      if(res.errcode !== 0) return
      let rows = res.data.row,
          searchList = [],
          dateKey = {},
          proArr = []
      rows.forEach(row => {
        // pages/statistics_report/report_show.html setFilter，只显示 datetime 和 reference1 两种类型
        if(row.is_search && ['datetime', 'reference1', ].includes(row.report_field_type)) {
          let { report_field_name, report_field_type, report_field_value, date_type, defaultValue, report_field_id, } = row,
              value = report_field_value.split(';')[0],
              arr = value.split('.'),
              obj = {
                field_name: report_field_name,
                type: report_field_type,
                field_id: report_field_id,
              }
          if(report_field_type === 'datetime') {
            defaultValue = [null, undefined, 'null', ''].includes(defaultValue) ? '' : defaultValue
            let dfltVal = defaultValue === '$NOW$' ? wx.$util.formatDate(new Date(), 'yyyy-MM-dd') : defaultValue

            obj.type = 'date'
            obj.fmt = date_type || 'yyyy-MM-dd'
            obj.start = dfltVal
            obj.end = dfltVal

            if(dfltVal) {
              let dfltLen = dfltVal.split('-').length
              if(dfltLen === 1) dfltVal += '-01-01'
              else if(dfltLen === 2) dfltVal += '-01'

              this.data.searchWhere.push({
                CompareValue: dfltVal + ' 00:00:00',
                CompareWith: obj.field_id,
                Operator: '>=',
                or: 0,
              })
              let endArr = dfltVal.split('-'),
                  end = wx.$util.formatDate(new Date(endArr[0], Number(endArr[1]) - 1, Number(endArr[2]) + 1), 'yyyy-MM-dd')
              this.data.searchWhere.push({
                CompareValue: end + ' 00:00:00',
                CompareWith: obj.field_id,
                Operator: '<',
                or: 0,
              })
            }

            if(obj.fmt !== 'yyyy-MM-dd') dateKey[report_field_id] = obj.fmt
          } else {
            let tableid = this.tableAlias[arr[0]]
            proArr.push(this.getOptionsList(tableid, arr[1], obj, defaultValue))
          }
          searchList.push(obj)
        }
      })

      Promise.all(proArr).then(res => {
        this.setData({
          searchList,
          searchWhere: this.data.searchWhere,
        })
        this.dateKey = dateKey

        this.getReportHtml()
      })
    })

  },
  getOptionsList(tableid, fieldid, obj, dfltVal) {
    return new Promise((resolve, reject) => {
      // 1.获取字段信息
      let post = {
        table: tableid,
        fieldname: fieldid,
      }
      wx.$post(4, 'QX/PRO_select_field', post).then(res => {
        if(res.errcode !== 0) return
        let mainEntity = res.data.row[0].mainEntity
        // 2.获取引用表主显示字段
        let p0 = new Promise((resolve, reject) => {
          wx.$post(3, 'Entity_param/query_entity_param', { table_id: mainEntity, }).then(res => {
            if(res.errcode !== 0) return
            resolve(res.data.row[0].entity_key)
          })
        })

        // 3.获取引用表数据
        let p1 = new Promise((resolve, reject) => {
          wx.$post(3, 'DynamicQuery/query_dynamic', { table_id: mainEntity, oby: `${mainEntity}.row_id desc`, }).then(res => {
            if(res.errcode !== 0) return
            let row = res.data.row,
                rows = row.length ? row[0] : []
            resolve(rows)
          })
        })

        Promise.all([p0, p1]).then(res => {
          obj.optionId = 'row_id'
          obj.optionName = res[0]
          obj.optionList = res[1]

          if(dfltVal === '$MONTH$') {
            let val = wx.$util.formatDate(new Date(), 'yyyy-MM').split('-').join('')
            obj.dfltVal = val
            this.data.searchWhere.push({
              CompareValue: val,
              CompareWith: obj.field_id,
              Operator: '=',
              or: 0,
            })
          }

          resolve()
        })
      })
    })
  },
  getReportHtml() {
    wx.showLoading({
      title: '加载中',
    })
    let post = {
      report_id: this.reportid,
      Format: 'html',
      Inline: true,
      file_name: '报表',
      order_by_list: '',
      Parameter: {
        children: [],
        filters: this.data.searchWhere,
        type: 'AND',
      },
    }

    this.setSearchVal()

    wx.$post(1, 'StatsReport/fastreport_disp', post, true, true).then(res => {
      wx.hideLoading()
      if(typeof res === 'object') {
        wx.$toast('报表查询出错！')
        return
      }
      // rich-text https://developers.weixin.qq.com/miniprogram/dev/component/rich-text.html
      // rich-text 不支持 style 节点，所以将内部样式转换成内联样式
      let htmlStr = res,
          // body字符串
          bodyStr = htmlStr.split('</head>')[1],
          // 内部显示样式字符串数组
          styleArr = bodyStr.match(/<style type=\"text\/css\">.*?<\/style>/g),
          styleStr = '',
          // 内部样式对象
          styleObj = null
      // 不含内部样式的body字符串
      bodyStr = bodyStr.replaceAll(/<style type=\"text\/css\" media=\"print\">.*<\/style>/g, '')

      // 1.获取内部样式对象
      if(styleArr.length) {
        styleStr = styleArr[0]
        styleStr = styleStr.replace('<style type="text/css">', '')
        styleStr = styleStr.replace('</style>', '')
        styleStr = styleStr.replace('<!--', '')
        styleStr = styleStr.replace('-->', '')

        // let classArr = styleStr.split('.s').filter(str => str.indexOf('{') > -1)
        let classArr = styleStr.match(/\{.*?\}/g)
        if(classArr.length) {
          styleObj = {}
          classArr.forEach((str, i) => {
            styleObj[`s${i}`] = str.slice(1, -1)
          })
        }
      }

      // 2.获取所有开始标签，将类名替换成相应的内联样式
      let elemArr = bodyStr.match(/<[a-zA-Z]+.*?>/g)
      elemArr.forEach((str, i) => {
        if(str.indexOf('<body') > -1) { // 设置body高宽
          let styleMatch = str.match(/style=".*?"/g),
              width = this.width,
              height = this.height,
              string = `width: fit-content; background: #fff;`
          if(styleMatch) {
            let styleStr = styleMatch[styleMatch.length - 1],
                styleArr = styleStr.split('style="')
            if(![null, undefined].includes(width)) string += `width: ${this.width}cm;`
            if(![null, undefined].includes(height)) string += `min-height: ${this.height}cm;`
            styleArr[0] = string
            elemArr[i] = str.replace(styleStr, `style="${styleArr.join('')}`)
          } else {
            if(![null, undefined].includes(width)) string += `width: ${this.width}cm;`
            if(![null, undefined].includes(height)) string += `min-height: ${this.height}cm;`
            elemArr[i] = str.replace('<body', `<body style="${string}"`)
          }
        }

        let clsMatch = str.match(/class=".*?"/g)
        if(clsMatch) {
          let clsStr = clsMatch[clsMatch.length - 1],
              clsName = clsStr.replace('class="', '').replace('"', ''),
              innerStyle = styleObj ? styleObj[clsName] : '',
              styleMatch = str.match(/style=".*?"/g)
          if(innerStyle) {  // 该类名有相应的内部样式
            if(styleMatch) {  // 元素已有内联样式，在内联样式中添加
              let styleStr = styleMatch[styleMatch.length - 1],
                  styleArr = styleStr.split('style="')
              styleArr[0] = innerStyle
              elemArr[i] = str.replace(styleStr, `style="${styleArr.join('')}`)
            } else {  // 元素没有内联样式，追加内联样式
              elemArr[i] = str.replace(clsStr, `${clsStr} style="${innerStyle}"`)
            }
          }
        }
      })

      // 3.将更改好的开始标签，替换原有的开始标签
      let splitArr = bodyStr.split(/<[a-zA-Z]+/g).filter(str => str)
      splitArr.forEach((str, i) => {
        let arr = str.match(/.*?>/g)
        arr[0] = elemArr[i]
        splitArr[i] = arr.join('')
      })

      // 4.rich-text 不支持 body 节点，所以将 body 更改为 div
      let tableStr = splitArr.join('').replace('<body', '<div')
      tableStr += `</div>`
      this.setData({
        tableHtml: tableStr,
      })
    })
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    wx.$setBarTitle();
    let { reportid, reportname, width, height, } = options
    this.reportid = reportid
    this.reportname = reportname
    this.width = width
    this.height = height
    this.dateKey = {}
    console.log(reportname);
    this.setData({
      tableName: reportname,
    })

    this.getTable().then(res => {
      this.getReportField()
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  },
})
